﻿
#ifndef WIN_TCP_CLIENT_TCP_CONN_H
#define WIN_TCP_CLIENT_TCP_CONN_H

#include <string>
#include <memory>
#include <functional>
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/SocketStream.h"
namespace zs
{
    using SkReadEventHandler = std::function<void(std::string& msg)>;
    using SkWriteEventHandler = std::function<void()>;
    using SkErrorEventHandler = std::function<void()>;
    class CEventLoop;
    class CTcpConn
    {
        CTcpConn() = default;
    public:
        static CTcpConn* get_instance();
        ~CTcpConn();
        /*
         * brief: 连接到服务器
         * param: ip 服务器ip地址
         * param: port 服务器端口
         * return: true: 连接成功 false: 连接失败
         */
        bool connect(const std::string &ip, int port);
        /*
         * brief: 设置读回调函数
         * param: callback 读回调函数
         */
        void set_read_callback(SkReadEventHandler callback);
        SkReadEventHandler get_read_callback();
        /*
         * brief: 设置写回调函数
         * param: callback 写回调函数
         */
        void set_write_callback(SkWriteEventHandler callback);
        SkWriteEventHandler get_write_callback();
        /*
         * brief: 设置错误回调函数
         * param: callback 错误回调函数
         */
        void set_error_callback(SkErrorEventHandler callback);
        SkErrorEventHandler get_error_callback() { return error_callback_; }
        /*
         * brief: 获取socket
         * return: socket
         */
        Poco::Net::StreamSocket& get_socket()
        {
            if(!connected_)
            {
                throw std::runtime_error("socket is not connected");
            }
            return socket_;
        }
        bool is_connected() const { return connected_; }
        void set_event_loop(CEventLoop* event_loop);
    private:
        void default_write_callback();
        void default_read_callback(std::string& msg);
    private:
        static std::unique_ptr<zs::CTcpConn> instance_;
        Poco::Net::StreamSocket socket_{};
        SkReadEventHandler read_callback_{};
        SkWriteEventHandler write_callback_{};
        SkErrorEventHandler error_callback_{};
        // 默认发送的数据包最大长度
        const size_t fixed_packet_len_ = 4096;
        //与服务器连接状态
        bool connected_{false};
        //ip地址
        std::string ip_;
        //端口
        int port_{};
        zs::CEventLoop* event_loop_{nullptr};
    };
}

#endif //WIN_TCP_CLIENT_TCP_CONN_H
